;; The first four lines of this file were added by Dracula.
;; They tell DrScheme that this is a Dracula Modular ACL2 program.
;; Leave these lines unchanged so that DrScheme can properly load this file.
#reader(planet "reader.rkt" ("cce" "dracula.plt") "modular" "lang")
(require "iphotonegative.lisp")
(require "mbmptree.lisp")

; The Photonegative module, which is responsible
; for taking in bitmap trees and producing a new
; image that's an inverted version of the original.
(module MPhotonegative
  (import Ibmptree)
  
  ; The helper function to Photonegative that actually does the processing.
  ; Goes through each pixel in the original image and subtracts each of its
  ; pixels' RGB values from 255 to invert the color.
  ;
  ; pre: oldtree - bitmap tree, the original image
  ;      newtree - the tree to store the new image in
  ;      xcurr - the x index in the outer for-loop, number
  ;      xmax - the max x value in the outer for-loop, number
  ;      ycurr - the y index in the inner for-loop, number
  ;      ymax - the max y value in the innter for-loop, number
  ; post: a new bitmap tree with the inverted image
  (defun photonegative-helper (oldtree newtree xcurr xmax ycurr ymax)
    ; is the current x index less than its max?
      (if (< xcurr xmax)
          ; yes, is the current y index less than its max?
          (if (< ycurr ymax)
              (let* ((currpixel (get-pixel-color oldtree xcurr ycurr))
                     ; get the original RGB values
                     (r (car currpixel))
                     (g (cadr currpixel))
                     (b (caddr currpixel))
                     ; calculate the new RGB values
                     (newr (- 255 r))
                     (newg (- 255 g))
                     (newb (- 255 b))
                     ; insert the new pixel into the tree
                     (tr (insert-pixel newtree (list xcurr ycurr (list newr newg newb)))))
                ; recursively call itself and process the next pixel
                (photonegative-helper oldtree tr xcurr xmax (+ ycurr 1) ymax))
              ; no, so reset y to 0 and increment x
              (photonegative-helper oldtree newtree (+ xcurr 1) xmax 0 ymax))
          ; x has extended past its max, so the recursion is done - return the new tree
          newtree))
  
  
  ; The photonegative function. Uses photonegative-helper
  ; to process each image in the pixel and put it in a new tree
  ; with an inverted color;
  ;
  ; pre: tree - a bitmap tree
  ; post: a new bitmap tree with an inverted image
  (defun photonegative (tree)
    (if (bmp-tree? tree)
        (let* ((oldheader (get-header tree))
               (oldheight (car (get-dimensions tree)))
               (oldwidth (cdr (get-dimensions tree)))
               (newtree (insert-header (empty-bmp-tree) oldheader)))
          (photonegative-helper tree newtree 0 oldheight 0 oldwidth))
        tree))
  
  (export IPhotonegative))